using DynamicProxies;
using DynamicProxies.Tests.Types;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;
using System.Reflection.Emit;

namespace DynamicProxies.Tests
{
	[TestClass]
	public sealed class ChangeExceptionTests : BaseTests
	{
		private bool createAfter;
		private bool createBefore;

		protected override sealed void OnSetup()
		{
			this.createAfter = false;
			this.createBefore = false;
		}

		[TestMethod, ExpectedException(typeof(InjectedException))]
		public void CreateExceptionBeforeCall()
		{
			this.createBefore = true;
			Proxy.Create<ExceptionalClass>(this).Safe();
		}

		[TestMethod, ExpectedException(typeof(InjectedException))]
		public void CreateExceptionAfterCall()
		{
			this.createAfter = true;
			Proxy.Create<ExceptionalClass>(this).Safe();
		}

		[TestMethod, ExpectedException(typeof(InjectedException))]
		public void ChangeExceptionAfterCall()
		{
			this.createBefore = true;
			Proxy.Create<ExceptionalClass>(this).Unsafe();
		}

		protected override sealed bool OnBeforeMethodInvocation(MethodBase target, object[] arguments)
		{
			if(target.Name == "Safe" && this.createBefore)
			{
				throw new InjectedException();
			}

			return true;
		}

		protected override sealed bool OnAfterMethodInvocation(MethodBase target, object[] arguments, ref object returnValue, Exception generatedException)
		{
			var throwException = false;

			if(target.Name == "Safe" && this.createAfter)
			{
				throw new InjectedException();
			}
			else if(target.Name == "Unsafe")
			{
				throw new InjectedException();
			}

			return throwException;
		}
	}
}
